﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using StockholmsStad.Data.Interfaces;
using StockholmsStad.Runtime.Serialization.DataContract;
using StockholmsStad.Runtime.Serialization.DataContract.Enums;
using StockholmsStad.Utilities.Exceptions;

namespace StockholmsStad.Data.Test
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class TestUnitBooking : TestUnitBase
    {
        // before running each test 
        [TestInitialize()]
        public void MyTestInitialize()
        {
            BeginTransaction();
        }

        // after each test has run
        [TestCleanup()]
        public void MyTestCleanup()
        {
            EndTransaction();
        }

        [TestMethod]
        public void GetNonExistingBooking()
        {
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            Booking booking = bookingAgent.GetBooking(context, DateTime.Now.Millisecond * DateTime.Now.Millisecond);

            Assert.AreEqual(booking, null, "Bokningen fanns");
        }


        [TestMethod]
        public void InsertAndRetrieveIndividualBooking()
        {
            IMinisterAgent ministerAgent = AgentFactory.GetMinisterAgent();
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            ministerAgent.AddMinister(context, TestEntity.GetNewMinister());
            Booking expected = TestEntity.GetIndividualBooking();
            int? ministerId = ministerAgent.GetMinisterIdByMinisterCode(context, expected.MinisterCode);

            int ticketId = CreateTicket();
            bookingAgent.AddBooking(context, ticketId, expected, ministerId.Value);

            Booking actual = bookingAgent.GetBooking(context, ticketId);

            AreBookingEqual(expected, actual);
        }

        [TestMethod]
        public void InsertAndCancelIndividualBooking()
        {
            IMinisterAgent ministerAgent = AgentFactory.GetMinisterAgent();
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            ministerAgent.AddMinister(context, TestEntity.GetNewMinister());
            Booking expected = TestEntity.GetIndividualBooking();
            int? ministerId = ministerAgent.GetMinisterIdByMinisterCode(context, expected.MinisterCode);

            ITicketAgent ticketAgent = AgentFactory.GetTicketAgent();
            User user = TestEntity.GetNewUser();
            Couple couple = TestEntity.GetNewCoupleWithoutContact();
            Ceremony ceremony = TestEntity.GetNewCeremony();

            ICeremonyAgent agent = AgentFactory.GetCeremonyAgent();

            var languageAgent = AgentFactory.GetLanguageAgent();
            var langId = languageAgent.AddLanguage(context, TestEntity.NewLanguage);
            Assert.AreNotEqual(0, langId, "Inget nytt språk skapades");

            var cerLangId = languageAgent.AddCeremonyLanguage(context, TestEntity.NewLanguage);
            Assert.AreNotEqual(0, cerLangId, "Inget nytt ceremoni språk skapades");

            var certLangId = languageAgent.AddCertificateLanguage(context, TestEntity.NewLanguage);
            Assert.AreNotEqual(0, certLangId, "Inget nytt certifikat språk skapades");

            ceremony.CeremonyLanguage.Id = cerLangId;
            ceremony.CertificateLanguage.Id = certLangId;

            var userAgent = AgentFactory.GetUserAgent();
            int userId = userAgent.CreateUser(context, user.Username, user.Password, (int)user.Role);
            Assert.AreNotEqual(0, userId, "Ingen användare skapades");

            int ticketId = ticketAgent.CreateTicket(context, couple, ceremony, userId);

            Assert.AreNotEqual(0, ticketId, "Skapades inget ärende");

            bookingAgent.AddBooking(context, ticketId, expected, ministerId);

            bookingAgent.RemoveBooking(context, ticketId, "testproject", user.Username, "Bokning avbokades");
            var emptyBooking = bookingAgent.GetBooking(context, ticketId);
            Assert.AreEqual(emptyBooking, null, "Bokningen togs ej bort");
        }

        [TestMethod]
        [ExpectedException(typeof(StockholmStadSystemException))]
        public void InsertAndCancelIndividualBookingWithNoMinister()
        {
            IMinisterAgent ministerAgent = AgentFactory.GetMinisterAgent();
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            ministerAgent.AddMinister(context, TestEntity.GetNewMinister());
            Booking expected = TestEntity.GetIndividualBooking();

            int ticketId = CreateTicket();
            bookingAgent.AddBooking(context, ticketId, expected, null);
        }

        [TestMethod]
        public void InsertAndCancelOrdinaryBooking()
        {
            ITicketAgent ticketAgent = AgentFactory.GetTicketAgent();
            User user = TestEntity.GetNewUser();
            Couple couple = TestEntity.GetNewCoupleWithoutContact();
            Ceremony ceremony = TestEntity.GetNewCeremony();

            ICeremonyAgent agent = AgentFactory.GetCeremonyAgent();

            var languageAgent = AgentFactory.GetLanguageAgent();
            var langId = languageAgent.AddLanguage(context, TestEntity.NewLanguage);
            Assert.AreNotEqual(0, langId, "Inget nytt språk skapades");

            var cerLangId = languageAgent.AddCeremonyLanguage(context, TestEntity.NewLanguage);
            Assert.AreNotEqual(0, cerLangId, "Inget nytt ceremoni språk skapades");

            var certLangId = languageAgent.AddCertificateLanguage(context, TestEntity.NewLanguage);
            Assert.AreNotEqual(0, certLangId, "Inget nytt certifikat språk skapades");

            ceremony.CeremonyLanguage.Id = cerLangId;
            ceremony.CertificateLanguage.Id = certLangId;

            var userAgent = AgentFactory.GetUserAgent();
            int userId = userAgent.CreateUser(context, user.Username, user.Password, (int)user.Role);
            Assert.AreNotEqual(0, userId, "Ingen användare skapades");

            int ticketId = ticketAgent.CreateTicket(context, couple, ceremony, userId);
            Assert.AreNotEqual(0, ticketId, "Inget ärende skapades");

            var bookingAgent = AgentFactory.GetBookingAgent();
            var maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            var timeblockId = maintenanceAgent.AddTimeBlock(context, TestEntity.GetNewTimeBlock());
            Assert.AreNotEqual(0, timeblockId, "Inget tidsblock lades till");
            Assert.IsNotNull(timeblockId, "Inget tidsblock lades till");

            var expected = TestEntity.GetOrdinaryBooking();
            expected.DateTime.TimeBlockId = timeblockId;

            bookingAgent.AddBooking(context, ticketId, expected, null);
            bookingAgent.RemoveBooking(context, ticketId, "testproject", user.Username, "avbokning");

            var emptyBooking = bookingAgent.GetBooking(context, ticketId);
            Assert.AreEqual(emptyBooking, null, "Bokningen togs ej bort");
        }

        [TestMethod]
        public void InsertAndRetrieveOrdinaryBooking()
        {
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            IMaintenanceAgent maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            var timeblockId = maintenanceAgent.AddTimeBlock(context, TestEntity.GetNewTimeBlock());
            Assert.AreNotEqual(0, timeblockId, "Inget tidsblock lades till");
            Booking expected = TestEntity.GetOrdinaryBooking();
            expected.DateTime.TimeBlockId = timeblockId;
            int ticketId = CreateTicket();
            bookingAgent.AddBooking(context, ticketId, expected, null);

            Booking actual = bookingAgent.GetBooking(context, ticketId);

            AreBookingEqual(expected, actual);
        }

        [TestMethod]
        public void InsertAndRetrieveOrdinaryBooking2()
        {
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            IMaintenanceAgent maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            var timeblock = TestEntity.GetNewTimeBlock();
            var timeblockId = maintenanceAgent.AddTimeBlock(context, timeblock);
            Assert.AreNotEqual(0, timeblockId, "Inget tidsblock skapades");

            Booking expected = TestEntity.GetOrdinaryBooking();
            expected.DateTime = null;
            expected.PreferredDate2 = null;

            expected.DateTime = timeblock;
            expected.DateTime.TimeBlockId = timeblockId;
            var ticketId = CreateTicket();
            bookingAgent.AddBooking(context, ticketId, expected, null);

            Booking actual = bookingAgent.GetBooking(context, ticketId);

            AreBookingEqual(expected, actual);
            Assert.AreEqual(expected.PreferredDate1, actual.PreferredDate1);
        }

        [TestMethod]
        public void AddBookingWithOnlyPreferredDates()
        {
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            var date1 = new DateTime(2008, 10, 10);
            var date2 = new DateTime(2008, 10, 11);
            var booking = new Booking
                                   {
                                       CeremonyType = CeremonyType.Ordinary,
                                       DateTime = null,
                                       PreferredDate1 = date1,
                                       PreferredDate2 = date2
                                   };

            var ticketId = CreateTicket();
            bookingAgent.AddBooking(context, ticketId, booking, null);

            Booking actual = bookingAgent.GetBooking(context, ticketId);

            Assert.AreEqual(new DateTime(date1.Year, date1.Month, date1.Day), actual.PreferredDate1.Value);
            Assert.AreEqual(new DateTime(date2.Year, date2.Month, date2.Day), actual.PreferredDate2);
        }

        [TestMethod]
        public void RemoveOrdinaryBooking()
        {
            ITicketAgent ticketAgent = AgentFactory.GetTicketAgent();
            User user = TestEntity.GetNewUser();
            Couple couple = TestEntity.GetNewCoupleWithoutContact();
            Ceremony ceremony = TestEntity.GetNewCeremony();

            ICeremonyAgent agent = AgentFactory.GetCeremonyAgent();

            var languageAgent = AgentFactory.GetLanguageAgent();
            var langId = languageAgent.AddLanguage(context, TestEntity.NewLanguage);
            Assert.AreNotEqual(0, langId, "Inget nytt språk skapades");

            var cerLangId = languageAgent.AddCeremonyLanguage(context, TestEntity.NewLanguage);
            Assert.AreNotEqual(0, cerLangId, "Inget nytt ceremoni språk skapades");

            var certLangId = languageAgent.AddCertificateLanguage(context, TestEntity.NewLanguage);
            Assert.AreNotEqual(0, certLangId, "Inget nytt certifikat språk skapades");

            ceremony.CeremonyLanguage.Id = cerLangId;
            ceremony.CertificateLanguage.Id = certLangId;

            var userAgent = AgentFactory.GetUserAgent();
            int userId = userAgent.CreateUser(context, user.Username, user.Password, (int)user.Role);
            Assert.AreNotEqual(0, userId, "Ingen användare skapades");

            int ticketId = ticketAgent.CreateTicket(context, couple, ceremony, userId);
            Assert.AreNotEqual(0, ticketId, "Inget ärende skapades"); 
            
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            IMaintenanceAgent maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            var timeblockId = maintenanceAgent.AddTimeBlock(context, TestEntity.GetNewTimeBlock());
            Booking expected = TestEntity.GetOrdinaryBooking();
            expected.DateTime.TimeBlockId = timeblockId;
            bookingAgent.AddBooking(context, ticketId, expected, null);

            bookingAgent.RemoveBooking(context, ticketId, "testproj", user.Username, "avbokning");

            var emptyBooking = bookingAgent.GetBooking(context, ticketId);
            Assert.AreEqual(emptyBooking, null, "Bokningen togs ej bort");
        }

        [TestMethod]
        public void RemoveIndividualBooking()
        {
            ITicketAgent ticketAgent = AgentFactory.GetTicketAgent();
            User user = TestEntity.GetNewUser();
            Couple couple = TestEntity.GetNewCoupleWithoutContact();
            Ceremony ceremony = TestEntity.GetNewCeremony();

            ICeremonyAgent agent = AgentFactory.GetCeremonyAgent();

            var languageAgent = AgentFactory.GetLanguageAgent();
            var langId = languageAgent.AddLanguage(context, TestEntity.NewLanguage);
            Assert.AreNotEqual(0, langId, "Inget nytt språk skapades");

            var cerLangId = languageAgent.AddCeremonyLanguage(context, TestEntity.NewLanguage);
            Assert.AreNotEqual(0, cerLangId, "Inget nytt ceremoni språk skapades");

            var certLangId = languageAgent.AddCertificateLanguage(context, TestEntity.NewLanguage);
            Assert.AreNotEqual(0, certLangId, "Inget nytt certifikat språk skapades");

            ceremony.CeremonyLanguage.Id = cerLangId;
            ceremony.CertificateLanguage.Id = certLangId;

            var userAgent = AgentFactory.GetUserAgent();
            int userId = userAgent.CreateUser(context, user.Username, user.Password, (int)user.Role);
            Assert.AreNotEqual(0, userId, "Ingen användare skapades");

            int ticketId = ticketAgent.CreateTicket(context, couple, ceremony, userId);
            Assert.AreNotEqual(0, ticketId, "Inget ärende skapades"); 
            
            IMinisterAgent ministerAgent = AgentFactory.GetMinisterAgent();
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            ministerAgent.AddMinister(context, TestEntity.GetNewMinister());
            Booking expected = TestEntity.GetIndividualBooking();
            int? ministerId = ministerAgent.GetMinisterIdByMinisterCode(context, expected.MinisterCode);

            bookingAgent.AddBooking(context, ticketId, expected, ministerId.Value);
            bookingAgent.RemoveBooking(context, ticketId, "testproj", user.Username, "avbokning");

            var emptyBooking = bookingAgent.GetBooking(context, ticketId);
            Assert.AreEqual(emptyBooking, null, "Bokningen togs ej bort");
        }

        /// <summary>
        /// Ändra tid
        /// </summary>
        [TestMethod]
        public void UpdateOrdinaryBooking()
        {
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            MinisterTimeBlock timeBlock = TestEntity.GetNewTimeBlock();
            IMaintenanceAgent maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            var timeblockId1 = maintenanceAgent.AddTimeBlock(context, timeBlock);
            Assert.AreNotEqual(0, timeblockId1, "Inget tidsblock lades till");
            Booking expected = TestEntity.GetOrdinaryBooking();
            expected.DateTime.TimeBlockId = timeblockId1;
            var ticketId = CreateTicket();
            bookingAgent.AddBooking(context, ticketId, expected, null);

            Booking updateBooking = bookingAgent.GetBooking(context, ticketId);
            AreBookingEqual(expected, updateBooking);

            timeBlock.StartDateTime = new DateTime(2010, 01, 01, 13, 45, 00);
            var timeblockId2 = maintenanceAgent.AddTimeBlock(context, timeBlock);
            Assert.AreNotEqual(0, timeblockId2, "Inget tidsblock lades till");

            updateBooking.PreferredDate1 = new DateTime(2020, 01, 01);
            updateBooking.PreferredDate2 = null;
            updateBooking.DateTime.StartDateTime = timeBlock.StartDateTime;
            updateBooking.DateTime.TimeBlockId = timeblockId2;
            bookingAgent.UpdateBooking(context, ticketId, updateBooking, null, "user1");

            Booking actual = bookingAgent.GetBooking(context, ticketId);
            AreBookingEqual(updateBooking, actual);
        }

        /// <summary>
        /// Avboka vanlig tid
        /// </summary>
        [TestMethod]
        public void UpdateOrdinaryBooking2()
        {
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            MinisterTimeBlock timeBlock = TestEntity.GetNewTimeBlock();
            IMaintenanceAgent maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            var timeblockId = maintenanceAgent.AddTimeBlock(context, timeBlock);
            Assert.AreNotEqual(0, timeblockId, "Inget tidsblock skapades");
            Booking expected = TestEntity.GetOrdinaryBooking();

            expected.DateTime = timeBlock;
            expected.DateTime.TimeBlockId = timeblockId;

            int ticketId = CreateTicket();
            bookingAgent.AddBooking(context, ticketId, expected, null);

            Booking updateBooking = bookingAgent.GetBooking(context, ticketId);
            AreBookingEqual(expected, updateBooking);

            updateBooking.PreferredDate2 = null;
            updateBooking.DateTime.TimeBlockId = timeblockId;
            bookingAgent.UpdateBooking(context, ticketId, updateBooking, null, "user1");

            Booking actual = bookingAgent.GetBooking(context, ticketId);
            AreBookingEqual(updateBooking, actual);
        }

        /// <summary>
        /// Behåll bokning, ändra preferrens
        /// </summary>
        [TestMethod]
        public void UpdateOrdinaryBooking3()
        {
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            MinisterTimeBlock timeBlock = TestEntity.GetNewTimeBlock();
            IMaintenanceAgent maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            var timeblockId = maintenanceAgent.AddTimeBlock(context, timeBlock);
            Assert.AreNotEqual(0, timeblockId, "Inget tidsblock skapades");

            Booking expected = TestEntity.GetOrdinaryBooking();
            expected.DateTime.TimeBlockId = timeblockId;

            int ticketId = CreateTicket();
            bookingAgent.AddBooking(context, ticketId, expected, null);

            Booking updateBooking = bookingAgent.GetBooking(context, ticketId);
            AreBookingEqual(expected, updateBooking);
            Assert.AreEqual(timeBlock.StartDateTime, updateBooking.DateTime.StartDateTime);

            updateBooking.PreferredDate1 = new DateTime(2020, 01, 01);
            updateBooking.PreferredDate2 = null;
            updateBooking.DateTime.StartDateTime = timeBlock.StartDateTime;
            updateBooking.DateTime.TimeBlockId = timeblockId;
            bookingAgent.UpdateBooking(context, ticketId, updateBooking, null, "user1");

            Booking actual = bookingAgent.GetBooking(context, ticketId);
            AreBookingEqual(updateBooking, actual);
            Assert.AreEqual(timeBlock.StartDateTime, updateBooking.DateTime.StartDateTime);
        }

        [TestMethod]
        public void UpdateIndividualBooking()
        {
            IMinisterAgent ministerAgent = AgentFactory.GetMinisterAgent();
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            ministerAgent.AddMinister(context, TestEntity.GetNewMinister());
            Booking expected = TestEntity.GetIndividualBooking();
            int? ministerId = ministerAgent.GetMinisterIdByMinisterCode(context, expected.MinisterCode);

            var ticketId = CreateTicket();
            bookingAgent.AddBooking(context, ticketId, expected, ministerId.Value);

            Booking updateBooking = bookingAgent.GetBooking(context, ticketId);
            AreBookingEqual(expected, updateBooking);

            Minister newMinister = TestEntity.GetNewMinister();
            const string newBookingCode = "Hejsan";
            newMinister.MinisterCode = newBookingCode;
            ministerAgent.AddMinister(context, newMinister);
            ministerId = ministerAgent.GetMinisterIdByMinisterCode(context, newBookingCode);
            updateBooking.MinisterCode = newBookingCode;
            updateBooking.DateTime = new TimeBlock {StartDateTime = new DateTime(2020, 01, 01)};
            bookingAgent.UpdateBooking(context, ticketId, updateBooking, ministerId, "user1");

            Booking actual = bookingAgent.GetBooking(context, ticketId);
            AreBookingEqual(updateBooking, actual);
        }

        /// <summary>
        /// From ordinary to individual
        /// </summary>
        [TestMethod]
        public void UpdateBookingFromOrdinaryToIndividual()
        {
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            IMaintenanceAgent maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            var timeblockId = maintenanceAgent.AddTimeBlock(context, TestEntity.GetNewTimeBlock());
            Assert.AreNotEqual(0, timeblockId, "Inget tidsblock skapades");
            Booking expected = TestEntity.GetOrdinaryBooking();
            expected.DateTime.TimeBlockId = timeblockId;

            int ticketId = CreateTicket();
            bookingAgent.AddBooking(context, ticketId, expected, null);

            Booking updateBooking = bookingAgent.GetBooking(context, ticketId);
            AreBookingEqual(expected, updateBooking);

            Minister newMinister = TestEntity.GetNewMinister();
            const string newBookingCode = "Hejsan";
            newMinister.MinisterCode = newBookingCode;
            IMinisterAgent ministerAgent = AgentFactory.GetMinisterAgent();
            ministerAgent.AddMinister(context, newMinister);
            int? ministerId = ministerAgent.GetMinisterIdByMinisterCode(context, newBookingCode);
            updateBooking.MinisterCode = newBookingCode;
            updateBooking.DateTime = new TimeBlock {StartDateTime = new DateTime(2020, 01, 01)};
            updateBooking.CeremonyType = CeremonyType.Individual;
            updateBooking.PreferredDate1 = null;
            updateBooking.PreferredDate2 = null;
            bookingAgent.UpdateBooking(context, ticketId, updateBooking, ministerId, "user1");

            Booking actual = bookingAgent.GetBooking(context, ticketId);
            AreBookingEqual(updateBooking, actual);
        }

        /// <summary>
        /// From individual to ordinary
        /// </summary>
        [TestMethod]
        public void UpdateIndividualBookingToOrdinary()
        {
            IMinisterAgent ministerAgent = AgentFactory.GetMinisterAgent();
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            ministerAgent.AddMinister(context, TestEntity.GetNewMinister());
            Booking expected = TestEntity.GetIndividualBooking();
            int? ministerId = ministerAgent.GetMinisterIdByMinisterCode(context, expected.MinisterCode);

            int ticketId = CreateTicket();
            bookingAgent.AddBooking(context, ticketId, expected, ministerId.Value);

            Booking updateBooking = bookingAgent.GetBooking(context, ticketId);
            AreBookingEqual(expected, updateBooking);

            MinisterTimeBlock timeBlock = TestEntity.GetNewTimeBlock();
            timeBlock.StartDateTime = new DateTime(2010, 01, 01, 13, 45, 00);
            IMaintenanceAgent maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            var timeblockId = maintenanceAgent.AddTimeBlock(context, timeBlock);
            Assert.AreNotEqual(0, timeblockId, "Inget tidsblock skapades");

            updateBooking.PreferredDate1 = new DateTime(2020, 01, 01);
            updateBooking.PreferredDate2 = null;
            updateBooking.DateTime.StartDateTime = timeBlock.StartDateTime;
            updateBooking.MinisterCode = null;
            updateBooking.CeremonyType = CeremonyType.Ordinary;

            updateBooking.DateTime.TimeBlockId = timeblockId;
            bookingAgent.UpdateBooking(context, ticketId, updateBooking, null, "user1");

            Booking actual = bookingAgent.GetBooking(context, ticketId);
            AreBookingEqual(updateBooking, actual);
        }

        public static void AreBookingEqual(Booking expected, Booking actual)
        {
            Assert.AreEqual(expected.CeremonyType, actual.CeremonyType);
            if (expected.DateTime != null || actual.DateTime != null)
                Assert.AreEqual(expected.DateTime.StartDateTime, actual.DateTime.StartDateTime, "Bokad tid matchade inte");
            if (expected.PreferredDate1 != null || actual.PreferredDate1 != null)
                Assert.AreEqual(expected.PreferredDate1, actual.PreferredDate1, "Önskad tid 1 matchade inte");
            if (expected.PreferredDate2 != null || actual.PreferredDate2 != null)
                Assert.AreEqual(expected.PreferredDate2, actual.PreferredDate2, "Önskad tid 2 matchade inte");
            Assert.AreEqual(expected.MinisterCode, actual.MinisterCode);
        }

        public static void AreTimeBlockEqual(MinisterTimeBlock expected, TimeBlock actual)
        {
            Assert.AreEqual(expected.StartDateTime, actual.StartDateTime);
        }

        [TestMethod]
        public void InsertTimeBlockTest()
        {
            MinisterTimeBlock expected = TestEntity.GetNewTimeBlock();
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            IMaintenanceAgent maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            maintenanceAgent.AddTimeBlock(context, expected);
            TimeBlock actual = bookingAgent.GetTimeBlockByStartDateTime(context, expected.StartDateTime);
            AreTimeBlockEqual(expected, actual);
        }

        /// <summary>
        /// Tidblock får inte ha samma starttid
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof (StockholmStadSystemException))]
        public void InsertDoubleTimeBlockTest()
        {
            MinisterTimeBlock expected = TestEntity.GetNewTimeBlock();
            IMaintenanceAgent maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            maintenanceAgent.AddTimeBlock(context, expected);
            maintenanceAgent.AddTimeBlock(context, expected);
        }

        /// <summary>
        /// Bara kontrollera att frågan körs
        /// </summary>
        [TestMethod]
        public void BasicGetFreeTimeBlocksTest()
        {
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            IEnumerable<TimeBlock> times = bookingAgent.GetFreeTimeBlockDateTimes(context,
                                                                                  new DateTime(2008, 01, 01));
            Assert.AreNotEqual(-1, times.Count());
        }

        /// <summary>
        /// Ta fram lediga tidblock. 
        /// Några raster
        /// </summary>
        [TestMethod]
        public void GetFreeTimeBlocksTest()
        {
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            DateTime fromDate = new DateTime(2008, 01, 01);
            int nrOfOldTimeblocks = bookingAgent.GetFreeTimeBlockDateTimes(context, fromDate).Count;
            // Object
            DateTime[] startTimes = new DateTime[7];
            int i = 0;
            IMaintenanceAgent maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            maintenanceAgent.AddTimeBlock(context,
                                          CreateBookableTimeBlock(
                                              startTimes[i++] = new DateTime(2008, 05, 05, 12, 30, 00)));
            maintenanceAgent.AddTimeBlock(context,
                                          CreateBreakTimeBlock(startTimes[i++] = new DateTime(2008, 05, 05, 12, 35, 00)));
            maintenanceAgent.AddTimeBlock(context,
                                          CreateBookableTimeBlock(
                                              startTimes[i++] = new DateTime(2008, 07, 05, 14, 00, 00)));
            maintenanceAgent.AddTimeBlock(context,
                                          CreateBookableTimeBlock(
                                              startTimes[i++] = new DateTime(2008, 06, 05, 12, 30, 00)));
            maintenanceAgent.AddTimeBlock(context,
                                          CreateBreakTimeBlock(startTimes[i++] = new DateTime(2008, 07, 05, 12, 30, 00)));
            maintenanceAgent.AddTimeBlock(context,
                                          CreateBookableTimeBlock(
                                              startTimes[i++] = new DateTime(2008, 06, 05, 13, 30, 00)));
            maintenanceAgent.AddTimeBlock(context,
                                          CreateBookableTimeBlock(
                                              startTimes[i++] = new DateTime(2008, 06, 05, 13, 35, 00)));
            // Replay
            List<TimeBlock> allTimeblocks = bookingAgent.GetFreeTimeBlockDateTimes(context, fromDate);
            int nrOfNewTimeblocks = allTimeblocks.Count;
            Assert.AreEqual(5, nrOfNewTimeblocks - nrOfOldTimeblocks);
            allTimeblocks.RemoveAll(t => !startTimes.Contains(t.StartDateTime));
            Assert.AreEqual(5, allTimeblocks.Count);
            Assert.AreEqual(allTimeblocks[0].StartDateTime, startTimes[0]);
            Assert.AreEqual(allTimeblocks[1].StartDateTime, startTimes[3]);
            Assert.AreEqual(allTimeblocks[2].StartDateTime, startTimes[5]);
            Assert.AreEqual(allTimeblocks[3].StartDateTime, startTimes[6]);
            Assert.AreEqual(allTimeblocks[4].StartDateTime, startTimes[2]);
        }

        /// <summary>
        /// Ta fram lediga tidblock. 
        /// Några raster och några bokade block
        /// </summary>
        [TestMethod]
        public void GetFreeTimeBlocksTest2()
        {
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            DateTime fromDate = new DateTime(2008, 01, 01);
            int nrOfOldTimeblocks = bookingAgent.GetFreeTimeBlockDateTimes(context, fromDate).Count;
            // Object
            DateTime[] startTimes = new DateTime[7];
            int[] ids = new int[7];
            int i = 0, a = 0;
            IMaintenanceAgent maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 05, 05, 12, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBreakTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 05, 05, 12, 35, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 07, 05, 14, 00, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 05, 12, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBreakTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 07, 05, 12, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 05, 13, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 05, 13, 35, 00)));
            MakeOrdinaryBooking(bookingAgent, startTimes[5], ids[5], "language1", "user1");
            MakeOrdinaryBooking(bookingAgent, startTimes[6], ids[6], "language2", "user2");
            // Replay
            List<TimeBlock> allTimeblocks = bookingAgent.GetFreeTimeBlockDateTimes(context, fromDate);
            int nrOfNewTimeblocks = allTimeblocks.Count;
            Assert.AreEqual(3, nrOfNewTimeblocks - nrOfOldTimeblocks);
            allTimeblocks.RemoveAll(t => !startTimes.Contains(t.StartDateTime));
            Assert.AreEqual(3, allTimeblocks.Count);
            Assert.AreEqual(allTimeblocks[0].StartDateTime, startTimes[0]);
            Assert.AreEqual(allTimeblocks[1].StartDateTime, startTimes[3]);
            Assert.AreEqual(allTimeblocks[2].StartDateTime, startTimes[2]);
        }

        /// <summary>
        /// Ta fram lediga tidblock. 
        /// Några raster och några bokade block. Kontrollera fråndatum
        /// </summary>
        [TestMethod]
        public void GetFreeTimeBlocksTest3()
        {
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            DateTime fromDate = new DateTime(2008, 06, 05);
            int nrOfOldTimeblocks = bookingAgent.GetFreeTimeBlockDateTimes(context, fromDate).Count;
            // Object
            DateTime[] startTimes = new DateTime[7];
            int[] ids = new int[7];
            int i = 0, a = 0;
            IMaintenanceAgent maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 05, 05, 12, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBreakTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 05, 05, 12, 35, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 07, 05, 14, 00, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 05, 12, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBreakTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 07, 05, 12, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 05, 13, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 05, 13, 35, 00)));
            MakeOrdinaryBooking(bookingAgent, startTimes[5], ids[5], "language1", "user1");
            MakeOrdinaryBooking(bookingAgent, startTimes[6], ids[6], "language2", "user2");
            // Replay
            List<TimeBlock> allTimeblocks = bookingAgent.GetFreeTimeBlockDateTimes(context, fromDate);
            int nrOfNewTimeblocks = allTimeblocks.Count;
            Assert.AreEqual(2, nrOfNewTimeblocks - nrOfOldTimeblocks);
            allTimeblocks.RemoveAll(t => !startTimes.Contains(t.StartDateTime));
            Assert.AreEqual(2, allTimeblocks.Count);
            Assert.AreEqual(allTimeblocks[0].StartDateTime, startTimes[3]);
            Assert.AreEqual(allTimeblocks[1].StartDateTime, startTimes[2]);
        }

        private int CreateTicket(string languageName, string username)
        {
            var ticketAgent = AgentFactory.GetTicketAgent();
            var user = TestEntity.GetNewUser();
            user.Username = username;
            var couple = TestEntity.GetNewCoupleWithoutContact();
            var ceremony = TestEntity.GetNewCeremony();

            var languageAgent = AgentFactory.GetLanguageAgent();
            var langId = languageAgent.AddLanguage(context, languageName);
            Assert.AreNotEqual(0, langId, "Inget språk lades till");

            var ceremonyAgent = AgentFactory.GetCeremonyAgent();
            var cerLangId = languageAgent.AddCeremonyLanguage(context, languageName);
            Assert.AreNotEqual(0, cerLangId, "Inget ceremonispråk lades till");

            var certLangId = languageAgent.AddCertificateLanguage(context, languageName);
            Assert.AreNotEqual(0, certLangId, "Inget certifikatspråk lades till");

            ceremony.CeremonyLanguage = new ValueIdPair { Name = languageName };
            ceremony.CertificateLanguage = new ValueIdPair { Name = languageName };

            var userAgent = AgentFactory.GetUserAgent();
            int userId = userAgent.CreateUser(context, user.Username, user.Password, (int)user.Role);
            Assert.AreNotEqual(0, userId, "Ingen användare skapades");
            user.UserId = userId;
            var ticketId = ticketAgent.CreateTicket(context, couple, ceremony, userId);
            Assert.AreNotEqual(0, ticketId, "Inget ärende skapades");
            return ticketId;
        }

        private int CreateTicket()
        {
            var ticketAgent = AgentFactory.GetTicketAgent();
            var user = TestEntity.GetNewUser();
            var couple = TestEntity.GetNewCoupleWithoutContact();
            var ceremony = TestEntity.GetNewCeremony();

            var languageAgent = AgentFactory.GetLanguageAgent();
            var langId = languageAgent.AddLanguage(context, TestEntity.NewLanguage);
            Assert.AreNotEqual(0, langId, "Inget språk lades till");

            var ceremonyAgent = AgentFactory.GetCeremonyAgent();
            var cerLangId = languageAgent.AddCeremonyLanguage(context, TestEntity.NewLanguage);
            Assert.AreNotEqual(0, cerLangId, "Inget ceremonispråk lades till");

            var certLangId = languageAgent.AddCertificateLanguage(context, TestEntity.NewLanguage);
            Assert.AreNotEqual(0, certLangId, "Inget certifikatspråk lades till");

            ceremony.CeremonyLanguage = new ValueIdPair { Name = TestEntity.NewLanguage };
            ceremony.CertificateLanguage = new ValueIdPair { Name = TestEntity.NewLanguage };

            var userAgent = AgentFactory.GetUserAgent();
            int userId = userAgent.CreateUser(context, user.Username, user.Password, (int)user.Role);
            Assert.AreNotEqual(0, userId, "Ingen användare skapades");
            user.UserId = userId;
            var ticketId = ticketAgent.CreateTicket(context, couple, ceremony, userId);
            Assert.AreNotEqual(0, ticketId, "Inget ärende skapades");
            return ticketId;
        }

        private void MakeOrdinaryBooking(IBookingAgent bookingAgent, DateTime dateTime, 
            int timeblockId, string languageName, string username)
        {
            int ticketId = CreateTicket(languageName, username);
            bookingAgent.AddBooking(context, ticketId, new Booking
                                                           {
                                                               CeremonyType = CeremonyType.Ordinary,
                                                               DateTime = new TimeBlock()
                                                                              {
                                                                                  StartDateTime = dateTime,
                                                                                  TimeBlockId = timeblockId,
                                                                    }
                                                 },
                                    null);
        }

        private static MinisterTimeBlock CreateBookableTimeBlock(DateTime dateTime)
        {
            return new MinisterTimeBlock
                       {
                           StartDateTime = dateTime,
                           Interval = 5,
                           TimeBlockStatus = TimeBlockStatus.Bookable,
                       };
        }

        private static MinisterTimeBlock CreateBreakTimeBlock(DateTime dateTime)
        {
            return new MinisterTimeBlock
                       {
                           StartDateTime = dateTime,
                           Interval = 5,
                           TimeBlockStatus = TimeBlockStatus.Break,
                       };
        }

        /// <summary>
        /// bara kontrollera att frågan körs
        /// </summary>
        [TestMethod]
        public void BasicGetBookedTimeBlocksTest()
        {
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            IEnumerable<TimeBlock> times = bookingAgent.GetBookedTimeBlockDates(context, new DateTime(2008, 01, 01));
            Assert.AreNotEqual(-1, times.Count());
        }

        /// <summary>
        /// Inga bokade tider
        /// </summary>
        [TestMethod]
        public void GetBookedTimeBlocksTest()
        {
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            DateTime fromDate = new DateTime(2008, 01, 01);
            int nrOfOldTimeblocks = bookingAgent.GetBookedTimeBlockDates(context, fromDate).Count();
            // Object
            DateTime[] startTimes = new DateTime[7];
            int i = 0;
            IMaintenanceAgent maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            maintenanceAgent.AddTimeBlock(context,
                                          CreateBookableTimeBlock(
                                              startTimes[i++] = new DateTime(2008, 05, 05, 12, 30, 00)));
            maintenanceAgent.AddTimeBlock(context,
                                          CreateBreakTimeBlock(startTimes[i++] = new DateTime(2008, 05, 05, 12, 35, 00)));
            maintenanceAgent.AddTimeBlock(context,
                                          CreateBookableTimeBlock(
                                              startTimes[i++] = new DateTime(2008, 07, 05, 14, 00, 00)));
            maintenanceAgent.AddTimeBlock(context,
                                          CreateBookableTimeBlock(
                                              startTimes[i++] = new DateTime(2008, 06, 05, 12, 30, 00)));
            maintenanceAgent.AddTimeBlock(context,
                                          CreateBreakTimeBlock(startTimes[i++] = new DateTime(2008, 07, 05, 12, 30, 00)));
            maintenanceAgent.AddTimeBlock(context,
                                          CreateBookableTimeBlock(
                                              startTimes[i++] = new DateTime(2008, 06, 05, 13, 30, 00)));
            maintenanceAgent.AddTimeBlock(context,
                                          CreateBookableTimeBlock(
                                              startTimes[i++] = new DateTime(2008, 06, 05, 13, 35, 00)));
            // Replay
            List<TimeBlock> allTimeblocks = bookingAgent.GetBookedTimeBlockDates(context, fromDate).ToList();
            int nrOfNewTimeblocks = allTimeblocks.Count;
            Assert.AreEqual(0, nrOfNewTimeblocks - nrOfOldTimeblocks);
            allTimeblocks.RemoveAll(t => !startTimes.Contains(t.StartDateTime));
            Assert.AreEqual(0, allTimeblocks.Count);
        }

        /// <summary>
        /// Enbart två bokade dagar. 
        /// Några raster och några bokade block
        /// </summary>
        [TestMethod]
        public void GetBookedTimeBlocksTest2()
        {
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            DateTime fromDate = new DateTime(2008, 01, 01);
            int nrOfOldTimeblocks = bookingAgent.GetBookedTimeBlockDates(context, fromDate).Count();
            // Object
            DateTime[] startTimes = new DateTime[8];
            int[] ids = new int[8];
            int i = 0, a = 0;
            IMaintenanceAgent maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 05, 05, 12, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBreakTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 05, 05, 12, 35, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 07, 05, 14, 00, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 05, 12, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBreakTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 07, 05, 12, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 06, 13, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 06, 13, 35, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 04, 13, 35, 00)));
            MakeOrdinaryBooking(bookingAgent, startTimes[5], ids[5], "language1", "user1");
            MakeOrdinaryBooking(bookingAgent, startTimes[6], ids[6], "language2", "user2");
            MakeOrdinaryBooking(bookingAgent, startTimes[7], ids[7], "language3", "user3");
            // Replay
            List<TimeBlock> allTimeblocks = bookingAgent.GetBookedTimeBlockDates(context, fromDate).ToList();
            int nrOfNewTimeblocks = allTimeblocks.Count;
            Assert.AreEqual(2, nrOfNewTimeblocks - nrOfOldTimeblocks);
            allTimeblocks.RemoveAll(t => !startTimes.Contains(t.StartDateTime));
            Assert.AreEqual(2, allTimeblocks.Count);
            Assert.AreEqual(allTimeblocks[0].StartDateTime, startTimes[7]);
            Assert.AreEqual(allTimeblocks[1].StartDateTime, startTimes[5]);
        }

        /// <summary>
        /// Enbart tre bokade dagar (varav en med ett bokat block och en rast). 
        /// Några raster och några bokade block
        /// </summary>
        [TestMethod]
        public void GetBookedTimeBlocksTest3()
        {
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            DateTime fromDate = new DateTime(2008, 01, 01);
            int nrOfOldTimeblocks = bookingAgent.GetBookedTimeBlockDates(context, fromDate).Count();
            // Object
            DateTime[] startTimes = new DateTime[8];
            int[] ids = new int[8];
            int i = 0, a = 0;
            IMaintenanceAgent maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 05, 05, 12, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBreakTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 05, 05, 12, 25, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 07, 05, 14, 00, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 05, 12, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBreakTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 07, 05, 12, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 06, 13, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 06, 13, 35, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 04, 13, 35, 00)));
            MakeOrdinaryBooking(bookingAgent, startTimes[5], ids[5], "language1", "user1");
            MakeOrdinaryBooking(bookingAgent, startTimes[6], ids[6], "language2", "user2");
            MakeOrdinaryBooking(bookingAgent, startTimes[7], ids[7], "language3", "user3");
            MakeOrdinaryBooking(bookingAgent, startTimes[0], ids[0], "language4", "user4");
            // Replay
            List<TimeBlock> allTimeblocks = bookingAgent.GetBookedTimeBlockDates(context, fromDate).ToList();
            int nrOfNewTimeblocks = allTimeblocks.Count;
            Assert.AreEqual(3, nrOfNewTimeblocks - nrOfOldTimeblocks);
            allTimeblocks.RemoveAll(t => !startTimes.Contains(t.StartDateTime));
            Assert.AreEqual(3, allTimeblocks.Count);
            Assert.AreEqual(allTimeblocks[0].StartDateTime, startTimes[0]);
            Assert.AreEqual(allTimeblocks[1].StartDateTime, startTimes[7]);
            Assert.AreEqual(allTimeblocks[2].StartDateTime, startTimes[5]);
        }

        /// <summary>
        /// Enbart två bokade dagar. 
        /// Några raster och några bokade block. Kontrollera fråndatum
        /// </summary>
        [TestMethod]
        public void GetBookedTimeBlocksTest4()
        {
            var bookingAgent = AgentFactory.GetBookingAgent();
            var fromDate = new DateTime(2008, 06, 06);
            var nrOfOldTimeblocks = bookingAgent.GetBookedTimeBlockDates(context, fromDate).Count();
            var startTimes = new DateTime[8];
            var ids = new int[8];
            int i = 0, a = 0;
            var maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 05, 05, 12, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBreakTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 05, 05, 12, 35, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 07, 05, 14, 00, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 05, 12, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBreakTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 07, 05, 12, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 06, 13, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 06, 13, 35, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 04, 13, 35, 00)));
            MakeOrdinaryBooking(bookingAgent, startTimes[5], ids[5], "language1", "user1");
            MakeOrdinaryBooking(bookingAgent, startTimes[6], ids[6], "language2", "user2");
            MakeOrdinaryBooking(bookingAgent, startTimes[7], ids[7], "language3", "user3");
            // Replay
            List<TimeBlock> allTimeblocks = bookingAgent.GetBookedTimeBlockDates(context, fromDate).ToList();
            int nrOfNewTimeblocks = allTimeblocks.Count;
            Assert.AreEqual(1, nrOfNewTimeblocks - nrOfOldTimeblocks);
            allTimeblocks.RemoveAll(t => !startTimes.Contains(t.StartDateTime));
            Assert.AreEqual(1, allTimeblocks.Count);
            Assert.AreEqual(allTimeblocks[0].StartDateTime, startTimes[5]);
        }

        /// <summary>
        /// Enbart en bokad dag och en delvis bokad dag. 
        /// Några raster och några bokade block
        /// </summary>
        [TestMethod]
        public void GetBookedTimeBlocksTest5()
        {
            var bookingAgent = AgentFactory.GetBookingAgent();
            var fromDate = new DateTime(2008, 01, 01);
            var nrOfOldTimeblocks = bookingAgent.GetBookedTimeBlockDates(context, fromDate).Count();
            // Object
            var startTimes = new DateTime[8];
            var ids = new int[8];
            int i = 0, a = 0;
            var maintenanceAgent = AgentFactory.GetMaintenanceAgent();
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 05, 05, 12, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBreakTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 05, 05, 12, 35, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 07, 05, 14, 00, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 05, 12, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBreakTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 07, 05, 12, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 06, 13, 30, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 06, 13, 35, 00)));
            ids[a++] =
                maintenanceAgent.AddTimeBlock(context,
                                              CreateBookableTimeBlock(
                                                  startTimes[i++] = new DateTime(2008, 06, 04, 13, 35, 00)));
            MakeOrdinaryBooking(bookingAgent, startTimes[5], ids[5], "language1", "user1");
            MakeOrdinaryBooking(bookingAgent, startTimes[7], ids[7], "language2", "user2");
            // Replay
            List<TimeBlock> allTimeblocks = bookingAgent.GetBookedTimeBlockDates(context, fromDate).ToList();
            int nrOfNewTimeblocks = allTimeblocks.Count;
            Assert.AreEqual(1, nrOfNewTimeblocks - nrOfOldTimeblocks);
            allTimeblocks.RemoveAll(t => !startTimes.Contains(t.StartDateTime));
            Assert.AreEqual(1, allTimeblocks.Count);
            Assert.AreEqual(startTimes[7], allTimeblocks[0].StartDateTime);
        }

        /// <summary>
        /// Testar de olika sendmetoderna med skickat mail
        /// </summary>
        [TestMethod]
        public void SendPreferredDateNotificationTest()
        {
            IBookingAgent bookingAgent = AgentFactory.GetBookingAgent();
            bookingAgent.SendPreferredDateNotification(context, new DateTime(2008, 01, 01));
        }

        public static void AreCeremonyEqual(Ceremony expected, Ceremony retrieved)
        {
            Assert.AreEqual(expected.CeremonyLanguage.Id, retrieved.CeremonyLanguage.Id,
                            string.Format("Expected ceremony language id ({0}) differs from recieved ({1})",
                                          expected.CeremonyLanguage, retrieved.CeremonyLanguage));
            Assert.AreEqual(expected.CertificateLanguage.Id, retrieved.CertificateLanguage.Id,
                            string.Format("Expected certificate language id ({0}) differs from recieved ({1})",
                                          expected.CertificateLanguage, retrieved.CertificateLanguage));

            Assert.AreEqual(expected.CeremonyLanguage.Name, retrieved.CeremonyLanguage.Name,
                            string.Format("Expected ceremony language Name ({0}) differs from recieved ({1})",
                                          expected.CeremonyLanguage, retrieved.CeremonyLanguage));
            Assert.AreEqual(expected.CertificateLanguage.Name, retrieved.CertificateLanguage.Name,
                            string.Format("Expected certificate language Name ({0}) differs from recieved ({1})",
                                          expected.CertificateLanguage, retrieved.CertificateLanguage));

            if (expected.SpecialNeeds != null || retrieved.SpecialNeeds != null)
            {
                Assert.AreEqual(expected.SpecialNeeds.Count, retrieved.SpecialNeeds.Count);
                for (int i = 0; i < expected.SpecialNeeds.Count; i++)
                {
                    Assert.AreEqual(expected.SpecialNeeds[i], retrieved.SpecialNeeds[i],
                                    string.Format("Expected needs ({0}) differs from recieved ({1})",
                                                  expected.SpecialNeeds[i], retrieved.SpecialNeeds[i]));
                }
            }
            Assert.AreEqual(expected.Interpreter, retrieved.Interpreter);

            Assert.AreEqual(expected.ImpedimentDocAllowDelayDays, retrieved.ImpedimentDocAllowDelayDays, "Delayded days matchar inte");
            Assert.AreEqual(expected.ImpedimentDocIssuedDate, retrieved.ImpedimentDocIssuedDate, "issued date matchar inte");
        }

    }
}